﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms.Layout;

namespace RelationTextBox
{
    public class DataGridview: System.Windows.Forms.DataGridView
    {
        protected int _lastVisibleColumn = 0;
        protected int _firstVisibleColumn = -1;
        public Boolean noTabProcess = false;
        public List<DataGridViewColumn> m_AutoCompletionColumns = new List<DataGridViewColumn>();
        public List<DataGridViewColumn> m_VerticalHeaderColumns = new List<DataGridViewColumn>();
        public Boolean EnableEvents = true;

        public DataGridview()
            : base()
        {
            Enter += new EventHandler(DataGridview_Enter);
            EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(DataGridview_EditingControlShowing);
                
            CellPainting += new DataGridViewCellPaintingEventHandler(DataGridview_CellPainting);
            CellLeave += new DataGridViewCellEventHandler(DataGridview_CellLeave);
            

        }

        void DataGridview_CellLeave(object sender, DataGridViewCellEventArgs e)
        {
            DataGridViewCell OwnerCell = ((DataGridView)sender).CurrentCell;
            ComboBox ctrl = ((DataGridView)sender).EditingControl as ComboBox;
            if (OwnerCell == null || OwnerCell.GetType()!=typeof(DataGridViewComboBoxCell) || ctrl==null)
                return;
            
            if (OwnerCell.FormattedValue.ToString() != ctrl.Text)
            {
                ctrl.BeginUpdate();
                int newIndex = ctrl.FindStringExact(ctrl.Text);
                if (ctrl.SelectedIndex != newIndex)
                {
                    ctrl.SelectedIndex = newIndex;
                    OwnerCell.Value = ctrl.SelectedValue;
                }
                ctrl.EndUpdate();
            }
        }

        void DataGridview_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {

            if (e.Control.GetType() == typeof(DataGridViewComboBoxEditingControl))
            {
                ComboBox ctrl = e.Control as ComboBox;
                if (ctrl.DropDownStyle != ComboBoxStyle.DropDown)
                {
                    ctrl.DropDownStyle = ComboBoxStyle.DropDown;
                    ctrl.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                    ctrl.AutoCompleteSource = AutoCompleteSource.ListItems;
                }
                
            }
        }

      

        void DataGridview_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (!EnableEvents || m_VerticalHeaderColumns.Count==0)
                return;
            if (e.RowIndex == -1)
            {
                foreach (DataGridViewColumn dc in m_VerticalHeaderColumns)
                    if (dc.Index == e.ColumnIndex)
                    {
                        e.PaintBackground(e.CellBounds, true);
                        RectangleF drawRect = new RectangleF(e.CellBounds.X + 5, e.CellBounds.Y, e.CellBounds.Width - 10, e.CellBounds.Height);
                        StringFormat drawFormat = new StringFormat();
                        drawFormat.FormatFlags = StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft | StringFormatFlags.NoClip;
                        e.Graphics.DrawString(e.FormattedValue.ToString(), e.CellStyle.Font, Brushes.Black, drawRect, drawFormat);
                        e.Handled = true;
                    }
            }
            
             
        }

              
        void DataGridview_Enter(object sender, EventArgs e)
        {
            _lastVisibleColumn = base.ColumnCount - 1;
            foreach (DataGridViewColumn col in Columns)
            {
                if (col.Visible && !col.ReadOnly)
                {
                    _lastVisibleColumn = col.Index;
                    if (_firstVisibleColumn == -1)
                    {                        
                        _firstVisibleColumn = col.Index;
                    }
                }
            }
            //MyTace("Prima coloana vizibila: " + _firstVisibleColumn.ToString());
            //MyTace("Ultima coloana vizibila: " + _lastVisibleColumn.ToString()); 
        }
        [System.Security.Permissions.UIPermission(
        System.Security.Permissions.SecurityAction.LinkDemand,
        Window = System.Security.Permissions.UIPermissionWindow.AllWindows)]

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected override void OnLeave(EventArgs e)
        {
            noTabProcess = false ;
            base.OnLeave(e);
        }
        
        protected override bool ProcessDialogKey(Keys keyData)
        {
            Keys key = (keyData & Keys.KeyCode);
            if (key == Keys.Enter)
            {
                return this.ProcessRightKey(keyData);
            }
            return base.ProcessDialogKey(keyData);
        }

        public new bool ProcessRightKey(Keys keyData)
        {
            noTabProcess = false;
            Keys key = (keyData & Keys.KeyCode);
            if (_lastVisibleColumn==0)
                _lastVisibleColumn = base.ColumnCount - 1;
            if (_firstVisibleColumn == -1)
                _firstVisibleColumn = 0;
            if (key == Keys.Enter)
            {
                if ((base.CurrentCell.ColumnIndex == _lastVisibleColumn) && (base.CurrentCell.RowIndex == base.RowCount-1))
                {
                    //if (base.CurrentRow.IsNewRow)
                     //   return base.ProcessRightKey(keyData);
                    try
                    {
                        ((BindingSource)base.DataSource).AddNew();
                    }
                    catch(Exception)
                    {
                        return false;
                    }
                    base.CurrentCell = base.Rows[base.RowCount - 1].Cells[_firstVisibleColumn];
                    return true;
                }

                if ((base.CurrentCell.ColumnIndex == _lastVisibleColumn) 
                    && (base.CurrentCell.RowIndex+1 <= base.RowCount-1))
                {
                    try
                    {
                        base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[_firstVisibleColumn];
                        noTabProcess = true;
                        //return false;
                    }
                    catch (Exception)
                    {
                        //return base.ProcessTabKey(keyData);
                        return false;
                    }
                    return true;
                }
                /*int step = base.CurrentCell.ColumnIndex + 1;
                while ((step < base.ColumnCount-1) && (base.Rows[base.CurrentCell.RowIndex].Cells[step].ReadOnly ||
                    !base.Rows[base.CurrentCell.RowIndex].Cells[step].Visible))
                    step++;
                if (step < base.ColumnCount)
                {
                    try
                    {
                        base.CurrentCell = base.Rows[base.CurrentCell.RowIndex].Cells[step];
                    }
                    catch(InvalidOperationException) //daca renunta sa treaca in campul urmator
                    {
                        //noTabProcess = true;
                    }
                }
                else
                {
                    if (base.CurrentCell.RowIndex + 1 < base.RowCount)
                    {
                        base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[_firstVisibleColumn];
                        noTabProcess = true;
                    }
                }
                ///move to next control
                ///
                
                return true;*/
                noTabProcess = true;
                return base.ProcessRightKey(keyData);
            }
            return base.ProcessRightKey(keyData);
        }

        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                return this.ProcessRightKey(e.KeyData);
            }
            return base.ProcessDataGridViewKey(e);
        }



        
    }
}
